<template>
  <div class="app-detail">
    <div class="common-content wh100 app-info-group">
      <div class="app-info-left">
        <div class="info-group">
          <el-scrollbar style="height: 100%">
            <div class="info-item">
              <table class="app-info-table" v-if="appinfoList">
                <colgroup>
                  <col width="90">
                  <col width="">
                </colgroup>
                <tr>
                  <td class="label-name">应用名称:</td>
                  <td>{{ appinfoList.appName }}</td>
                </tr>
                <tr>
                  <td class="label-name">运行状态:</td>
                  <td>
                    <span v-if="appinfoList.appRunState == 0">运行完成</span>
                    <span v-else-if="appinfoList.appRunState == 1">运行异常</span>
                    <span v-else>未运行</span>
                  </td>
                </tr>
                <tr>
                  <td class="label-name">应用类型:</td>
                  <td>
                    <span v-if="appinfoList.appType == 1">独立应用</span>
                    <span v-else>组合应用</span>
                  </td>
                </tr>
                <tr>
                  <td class="label-name">版本号:</td>
                  <td>{{ appinfoList.appVersion }}</td>
                </tr>
                <tr>
                  <td class="label-name">组件数量:</td>
                  <td>{{ appinfoList.pluginsNum}}</td>
                </tr>
                <tr>
                  <td class="label-name">是否切换:</td>
                  <td>
                    <span v-if="appinfoList.isSwitch == 0">切换</span>
                    <span v-else>不切换</span>
                  </td>
                </tr>
                <tr>
                  <td class="label-name">是否监控:</td>
                  <td>{{ appinfoList.isMonitor == 0 ? "监控" : "不监控" }}</td>
                </tr>
                <tr>
                  <td class="label-name">创建时间:</td>
                  <td>{{ appinfoList.addTime}}</td>
                </tr>
                <tr>
                  <td class="label-name">修改时间:</td>
                  <td>{{appinfoList.editTime || '--'}}</td>
                </tr>
                <tr>
                  <td class="label-name">版本说明:</td>
                  <td>{{ appinfoList.appRemarks || '--' }}</td>
                </tr>
                <tr>
                  <td class="label-name">场景描述:</td>
                  <td>{{ appinfoList.appScene || '--'}}</td>
                </tr>
              </table>
            </div>
            <div class="info-item" v-if="appinfoListRequire">
              <table class="app-info-table">
                <colgroup>
                  <col width="90">
                  <col width="">
                </colgroup>
                <tr>
                  <th colspan="2">环境信息</th>
                </tr>
                <tr>
                  <td class="label-name">最小CPU:</td>
                  <td>{{ appinfoListRequire.requireCPU }}</td>
                </tr>
                <tr>
                  <td class="label-name">最小GPU:</td>
                  <td>{{appinfoListRequire.requireGPU}}</td>
                </tr>
                <tr>
                  <td class="label-name">最小存储:</td>
                  <td>{{appinfoListRequire.requireDisk}}</td>
                </tr>
                <tr>
                  <td class="label-name">运行内存:</td>
                  <td>{{ appinfoListRequire.requireMemory }}</td>
                </tr>
                <tr>
                  <td class="label-name">场景描述:</td>
                  <td colspan="7">{{ appinfoListRequire.remarks || '--'}}</td>
                </tr>
              </table>
            </div>
            <div class="info-item" v-if="appinfoListSwitch">
              <table class="app-info-table">
                <colgroup>
                  <col width="90">
                  <col width="">
                </colgroup>
                <tr>
                  <th colspan="2">切换配置</th>
                </tr>
                <tr>
                  <td class="label-name">切换名称:</td>
                  <td>{{ appinfoListSwitch.switchName }}</td>
                </tr>
                <tr>
                  <td class="label-name">切换地址:</td>
                  <td>{{ appinfoListSwitch.switchAddress }}</td>
                </tr>
              </table>
            </div>
            <div class="info-item" v-if="appinfoListMonitor">
              <table class="app-info-table">
                <colgroup>
                  <col width="90">
                  <col width="">
                </colgroup>
                <tr>
                  <th colspan="2">监控配置</th>
                </tr>
                <tr>
                  <td class="label-name">监控频率:</td>
                  <td>{{ appinfoListMonitor.monitorRate }}</td>
                </tr>
                <tr>
                  <td class="label-name">监控类型:</td>
                  <td>
                    {{appinfoListMonitor.monitorType == 0 ? "进程监控" : appinfoListMonitor.monitorType == 1 ? "数据监控" :
                    "全部"}}
                  </td>
                </tr>
              </table>
            </div>
          </el-scrollbar>
        </div>
      </div>
      <div class="app-info-right">
        <el-scrollbar style="height: 100%">
          <!--组件信息详情-->
          <table class="app-info-table" v-if="pluginsInfo">
            <tr>
              <th colspan="2">组件 {{ pName }} 信息详情</th>
            </tr>

            <tbody v-if="pluginsInfo.pfunctionList">
            <tr>
              <th colspan="2">函数信息</th>
            </tr>
            <tr v-for="(item, index) in pluginsInfo.pfunctionList"
                :key="index">
              <td>
                <div class="text-item">
                  <div class="text-item-label">函数名:</div>
                  <div class="text-item-cont">{{item.functionName}}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">入参类型:</div>
                  <div class="text-item-cont">{{ item.paramInputClass }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">入 参 值:</div>
                  <div class="text-item-cont"> {{ item.text  }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">运行内存要求:</div>
                  <div class="text-item-cont">{{ item.paramOutputClass }}</div>
                </div>
              </td>
            </tr>
            </tbody>

            <tbody v-if="pluginsInfo.parequire">
            <tr>
              <th colspan="2">环境信息</th>
            </tr>
            <tr>
              <td>
                <div class="text-item">
                  <div class="text-item-label">最小CPU:</div>
                  <div class="text-item-cont">{{pluginsInfo.parequire.requireCPU}}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">最小GPU:</div>
                  <div class="text-item-cont">{{ pluginsInfo.parequire.requireGPU }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">最小存储单元:</div>
                  <div class="text-item-cont"> {{ pluginsInfo.parequire.requireDisk }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">运行内存要求:</div>
                  <div class="text-item-cont">{{ pluginsInfo.parequire.requireMemory }}</div>
                </div>
              </td>
            </tr>
            </tbody>
            <tbody v-if="pluginsInfo.pamonitor">
            <tr>
              <th colspan="2">监控信息</th>
            </tr>
            <tr>
              <td>
                <div class="text-item">
                  <div class="text-item-label">监控频率:</div>
                  <div class="text-item-cont"> {{ pluginsInfo.pamonitor.monitorRate }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">监控类型:</div>
                  <div class="text-item-cont">
                    {{pluginsInfo.pamonitor.monitorType == 0 ? "进程监控": pluginsInfo.pamonitor.monitorType == 1?
                    "数据监控" : "全部" }}
                  </div>
                </div>
              </td>
            </tr>
            </tbody>
            <tbody v-if="pluginsInfo.paswitch">
            <tr>
              <th colspan="2">切换信息</th>
            </tr>
            <tr>
              <td>
                <div class="text-item">
                  <div class="text-item-label">监控频率:</div>
                  <div class="text-item-cont"> {{ pluginsInfo.paswitch.switchName }}</div>
                </div>
                <div class="text-item">
                  <div class="text-item-label">监控类型:</div>
                  <div class="text-item-cont">{{ pluginsInfo.paswitch.switchAddress }}</div>
                </div>
              </td>
            </tr>
            </tbody>
            <tbody v-if="!pluginsInfo.paswitch && !pluginsInfo.pamonitor && !pluginsInfo.parequire &&!pluginsInfo.pfunctionList">
            <tr>
              <td>
                <div class="empty-body">
                  暂无信息
                </div>
              </td>
            </tr>
            </tbody>
          </table>

          <!--连线关系详情-->
          <div class="info-item" v-if="lineInfo.length">
            <table class="app-info-table">
              <tr>
                <th colspan="2">连线关系详情</th>
              </tr>
              <tr v-for="(item, index) in lineInfo" :key="index">
                <td>
                  <div class="text-item">
                    <div class="text-item-label">线类型:</div>
                    <div class="text-item-cont">
                      {{item.relationLineType == 0 ? "数据线" : item.relationLineType == 1 ? "状态线" : "控制线"}}
                    </div>
                  </div>
                  <div class="text-item">
                    <div class="text-item-label">输出类型:</div>
                    <div class="text-item-cont">
                      {{item.relationOutType == 0 ? "单值" : item.relationOutType == 1 ? "JSON" : "结构体"}}
                    </div>
                  </div>
                  <div class="text-item">
                    <div class="text-item-label">源函数:</div>
                    <div class="text-item-cont">{{item.SName}}</div>
                  </div>
                  <div class="text-item">
                    <div class="text-item-label">目标函数:</div>
                    <div class="text-item-cont">{{item.TName}}</div>
                  </div>
                  <div class="text-item">
                    <div class="text-item-label">输出参数位置:</div>
                    <div class="text-item-cont">{{item.relationLineInputIndex}}</div>
                  </div>
                </td>
              </tr>
            </table>
          </div>
        </el-scrollbar>
      </div>

      <div class="graph-box" ref="graphBox"></div>
    </div>
  </div>
</template>

<script>

import {Graph, Line, Path, Curve} from "@antv/x6";
import {get_getAppLineInfo, get_selectPFunctionByPluginsId} from "@/apis/comList/comList";
import {arrayGroup} from '@/utils'

Graph.registerConnector(
  'multi-smooth',
  (
    sourcePoint,
    targetPoint,
    routePoints,
    options,
  ) => {
    const {index = 0, total = 1, gap = 12} = options
    const line = new Line(sourcePoint, targetPoint)
    const centerIndex = (total - 1) / 2
    const dist = index - centerIndex
    const diff = Math.abs(dist)
    const factor = diff === 0 ? 1 : diff / dist
    const vertice = line.pointAtLength(line.length() / 2 + gap * factor * Math.ceil(diff)).rotate(90, line.getCenter())

    const points = [sourcePoint, vertice, targetPoint]
    const curves = Curve.throughPoints(points)
    const path = new Path(curves)
    return options.raw ? path : path.serialize()
  },
  true
)
let initGraph = null
export default {
  name: "AppDetail",
  data() {
    return {
      details: null,
      appinfoList: null,
      appinfoListRequire: null,
      appinfoListSwitch: null,
      appinfoListMonitor: null,
      pName: '',
      lineInfo: [],
      pluginsInfo: null
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initX6()
      this.getDetails()
    })
  },
  created() {

  },
  methods: {
    // 初始化渲染x6
    initX6() {
      initGraph = new Graph({
        container: this.$refs.graphBox,
        background: {
          color: "rgba(255,255,255,0.1)",
        },
        mousewheel: true, //鼠标轮滚缩放
        panning: true, //支持平移拖拽
        snapline: true, //对齐线
        interacting: false,
      });
      initGraph.centerContent();
      initGraph.zoom(-0.2);

      initGraph.on("edge:dblclick", (e) => {
        get_getAppLineInfo({
          lineId: e.cell.labels[0].attrs.labelText.lId,
        }).then((res) => {
          let {data} = res.data;
          data.forEach((item) => {
            item.funtionList.forEach((tem) => {
              if (item.relationLineSource == tem.id) {
                item.SName = tem.functionName;
              }
              if (item.relationLineTarget == tem.id) {
                item.TName = tem.functionName;
              }
            });
          });
          this.lineInfo = data;
          this.pluginsInfo = null;
        });
      });
      initGraph.on("node:dblclick", (e) => {
        this.pName = e.cell.label;
        get_selectPFunctionByPluginsId({pluginsId: e.cell.id}).then((res) => {
          let {data} = res.data;
          data.pfunctionList.forEach((item) => {
            let arr = item.paramInputClass.split(",");
            arr.forEach((text, index) => {
              arr[index] = "被占用";
            });
            item.adataList.forEach((tem) => {
              if (item.id == tem.ftId) {
                arr[tem.aindex] = tem.avalue;
              }
            });
            item.text = arr.join(",");
          });
          this.pluginsInfo = data;
          this.lineInfo = [];
        });
      });
    },
    getDetails() {
      this.appInfoData = {
        nodes: [],
        edges: [],
      };
      this.$api.appliesInfo({appId: this.$route.query.appid}).then((res) => {
        let {data} = res.data;
        this.appinfoList = data.applies;
        this.appinfoList.addTime = this.$moment(this.appinfoList.addTime).format("YYYY-MM-DD");
        if (this.appinfoList.editTime) {
          this.appinfoList.editTime = this.$moment(this.appinfoList.editTime).format("YYYY-MM-DD");
        }

        this.appinfoListRequire = data.parequire;
        this.appinfoListSwitch = data.paswitch;
        this.appinfoListMonitor = data.pamonitor;

        // 获取源id与目标id数组去重
        let nodeId = [];
        if (data.arelation.length > 0) {
          data.arelation.forEach((item, index) => {
            //relationLineType
            this.appInfoData.edges.push({
              source: item.relationLineSource,
              target: item.relationLineTarget,
              // connector: {
              //   name: 'multi-smooth',
              //   args: {
              //     total: 2,
              //     index: index,
              //   },
              // },
              labels: [
                {
                  markup: [
                    {
                      tagName: "rect",
                      selector: "labelBody",
                    },
                    {
                      tagName: "text",
                      selector: "labelText",
                    },
                  ],
                  attrs: {
                    labelText: {
                      text: " ",
                      lId: item.relationLineId,
                    },
                    labelBody: {
                      ref: "labelText",
                      refY: 3,
                      refWidth: 4,
                      refHeight: -6,
                      fill: item.relationLineType === 0 ? "#267ff7" : item.relationLineType === 1 ? "#45D9BF" : "#fd9f6c",
                    },
                  },
                  position: item.relationLineType === 0 ? 0.3 : item.relationLineType === 1 ? 0.5 : 0.54,
                },
              ],
              attrs: {
                line: {
                  stroke: '#ffffff',
                },
                body: {
                  fill: '#f5f5f5'
                },
              }
            });
            nodeId.push(item.relationLineSource);
            nodeId.push(item.relationLineTarget);
          });
          nodeId = Array.from(new Set(nodeId));
          let nodeInfo = {};
          let arr = [];
          nodeId.forEach((item) => {
            nodeInfo[item] = "";
            arr.push(
              data.arelation.find((res) => {
                return item == res.relationLineSource || item == res.relationLineTarget;
              })
            );
          });
          arr.forEach((item) => {
            if (!nodeInfo[item.relationLineSource]) {
              nodeInfo[item.relationLineSource] = {
                id: item.relationLineSource, // String，可选，节点的唯一标识
                x: item.relationLineSourceXaxis, // Number，必选，节点位置的 x 值
                y: item.relationLineSourceYaxis, // Number，必选，节点位置的 y 值
                width: 160, // Number，可选，节点大小的 width 值
                height: 60, // Number，可选，节点大小的 height 值
                label: item.sourcePluginsName, // String，节点标签
                attrs: {
                  body: {
                    fill: '#ffffff',
                    // stroke: '#9254de',
                    rx: 10,
                    ry: 10
                  }
                }
              }
            }
            if (!nodeInfo[item.relationLineTarget]) {
              nodeInfo[item.relationLineTarget] = {
                id: item.relationLineTarget, // String，可选，节点的唯一标识
                x: item.relationLineTargetXaxis, // Number，必选，节点位置的 x 值
                y: item.relationLineTargetYaxis, // Number，必选，节点位置的 y 值
                width: 160, // Number，可选，节点大小的 width 值
                height: 60, // Number，可选，节点大小的 height 值
                label: item.targetPluginsName, // String，节点标签
                attrs: {
                  body: {
                    fill: '#ffffff',
                    // stroke: '#9254de',
                    rx: 10,
                    ry: 10
                  }
                }
              }
            }
          });
          for (const key in nodeInfo) {
            this.appInfoData.nodes.push(nodeInfo[key]);
          }
          this.pName = this.appInfoData.nodes[1].label;
          get_selectPFunctionByPluginsId({
            pluginsId: this.appInfoData.nodes[1].id,
          }).then((res) => {
            let {data} = res.data;
            data.pfunctionList.forEach((item) => {
              let arr = item.paramInputClass.split(",");
              arr.forEach((text, index) => {
                arr[index] = "被占用";
              });
              item.adataList.forEach((tem) => {
                if (item.id == tem.ftId) {
                  arr[tem.aindex] = tem.avalue;
                }
              });
              item.text = arr.join(",");
            });
            this.pluginsInfo = data;
          });
        }
        // 渲染图像
        initGraph.fromJSON(this.appInfoData);
      });
    }
  }
}
</script>

<style scoped lang="less">
  .app-detail {
    height: 100%;
    width: 100%;

    .app-info-group {
      position: relative;

      .app-info-left {
        position: absolute;
        width: 300px;
        left: 0;
        top: 0;
        /*background-color: rgba(255, 255, 255, 0.2);*/
        z-index: 100;
        height: 100%;
        overflow: hidden;

        .info-group {
          height: 100%;
          overflow: hidden;
          padding: 10px;
        }
      }

      .app-info-right {
        position: absolute;
        width: 300px;
        right: 0;
        top: 0;
        z-index: 100;
        padding: 10px;
        height: 100%;
        overflow: hidden;
      }

      .app-info-table {
        width: 100%;
        border-spacing: 0;
        border-top: 1px solid #e8e8e8;
        border-left: 1px solid #e8e8e8;
        margin-bottom: 10px;
        color: #ffffff;
        background-color: rgba(0, 0, 0, 0.3);


        th {
          padding: 5px 10px;
          border-right: 1px solid #e8e8e8;
          border-bottom: 1px solid #e8e8e8;
          line-height: 1.5;
        }

        td {
          padding: 5px 10px;
          border-right: 1px solid #e8e8e8;
          border-bottom: 1px solid #e8e8e8;
          line-height: 1.5;
        }

        .label-name {
          text-align: right;
        }
      }

      .text-item {
        display: flex;
        align-items: center;
        margin-bottom: 10px;

        .text-item-label {
          text-align: right;
          width: 100px;
          margin-right: 10px;
        }
      }

      .empty-body {
        height: 100px;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }

    .graph-box {
      width: 100%;
      height: 100%;
    }
  }
</style>